use std::any::type_name;
use std::io::Cursor;
use std::num::TryFromIntError;
use std::ops::BitAnd;
use std::string::FromUtf8Error;
use std::thread::sleep;

use bytes::{Buf, Bytes};
use log::log_enabled;
use tokio::io::AsyncRead;

use crate::{safe_pin, thread_safe_ptr, thread_safe_slice, unsafe_assign};
use crate::utils::cache_model::*;
use crate::utils::ThreadSafePtr;

use super::tools::Error;

///包装接受和发送的数据用来包装成为可以处理的帧(主要用于解析buffer中每个字符含义，以及处理逻辑)
#[derive(Debug)]
pub enum Frame {
    Simple(String),
    Error(String),
    Int(u64),
    Bulk(Bytes),
    Null,
    Array(Vec<Frame>),
}

//一些Frame相关的异常处理
#[derive(Debug)]
pub enum FrameError {
    InCompletable,
    Other(Error),
}

impl Frame {
    //主要用于
    pub fn array() -> Frame {
        Frame::Array(vec![])
    }
    pub fn array_with_size(size: usize) -> Frame {
        let mut vec = Vec::new();
        vec.reserve(size - (size & 1));
        Frame::Array(vec)
    }
    pub fn push_bulk(&mut self, val: Bytes) {
        match self {
            Frame::Array(vec) => {
                vec.push(Frame::Bulk(val));
            }
            _ => panic!("not an array frame"),
        }
    }

    pub fn push_int(&mut self, val: u64) {
        match self {
            Frame::Array(vec) => {
                vec.push(Frame::Int(val));
            }
            _ => panic!("not an array frame"),
        }
    }

    pub fn parse_check<'a>(src: &mut Cursor<&'a [u8]>) -> Result<CacheCap<Frame>, FrameError> {
        match get_u8(src)? {
            b'+' | b'-' => {
                // thread_safe_ptr! {
                //     let line_ref = get_line(src)?;
                // }
                let ptr = ThreadSafePtr::capture(get_line(src)?);
                Ok(CacheCap::of(move || {
                    Frame::Simple(String::from_utf8(ptr.to_vec()).unwrap())
                }))
            }
            _ => unimplemented!(),
        }
    }
}

fn get_u8(src: &mut Cursor<&[u8]>) -> Result<u8, FrameError> {
    if !src.has_remaining() {
        return Err(FrameError::InCompletable);
    }

    Ok(src.get_u8())
}

fn get_line<'a>(src: &mut Cursor<&'a [u8]>) -> Result<&'a [u8], FrameError> {
    // Scan the bytes directly
    let start = src.position() as usize;
    // Scan to the second to last byte
    let end = src.get_ref().len() - 1;

    for i in start..end {
        if src.get_ref()[i] == b'\r' && src.get_ref()[i + 1] == b'\n' {
            // We found a line, update the position to be *after* the \n
            src.set_position((i + 2) as u64);

            // Return the line
            return Ok(&src.get_ref()[start..i]);
        }
    }

    Err(FrameError::InCompletable)
}

impl From<String> for FrameError {
    fn from(src: String) -> FrameError {
        FrameError::Other(src.into())
    }
}

impl From<&str> for FrameError {
    fn from(src: &str) -> FrameError {
        src.to_string().into()
    }
}

impl From<FromUtf8Error> for FrameError {
    fn from(_src: FromUtf8Error) -> FrameError {
        "protocol error; invalid frame format".into()
    }
}

impl From<TryFromIntError> for FrameError {
    fn from(_src: TryFromIntError) -> FrameError {
        "protocol error; invalid frame format".into()
    }
}

#[test]
fn test_frame() {
    let vec = b"+ssss\r\n"[..].to_vec();
    let mut cursor = Cursor::new(&vec[..]);
    match Frame::parse_check(&mut cursor) {
        Ok(frame_cap) => {
            println!("{:?}", frame_cap.visit());
        }
        Err(_) => {}
    }
}

fn tes_slice(cursor: &mut Cursor<&[u8]>) -> Option<CacheCap<i32>> {
    thread_safe_slice! {
                    let line_ref = get_line(cursor).unwrap();
                }
    Some(CacheCap::of(move || {
        unsafe {
            println!("{:?}", line_ref.to_slice().to_vec());
        }
        1
    }))
}

#[test]
fn test_slice_ref() {
    let vec = b"+ssss\r\n"[..].to_vec();
    let mut cursor = Cursor::new(&vec[..]);
    let func = tes_slice(&mut cursor);
    func.unwrap().visit();
}